﻿using AllInOne;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace CommunityGuider
{
    class ConsoleHome: IHomePage
    {
        #region Fields
        
        IList<string> samples = new List<string>();
        public ISampleReader SampleReader { get; set; }
        HomePresenter presenter;
       
        #endregion

        public ConsoleHome()
        {
            this.SampleReader = StructureMap.ObjectFactory.GetInstance<ISampleReader>();
            presenter = new HomePresenter(this);
        }

        #region IHomePage
        public event Action Render;


        public void Show()
        {
            AllocConsole();

            if (Render != null) Render();
        }

        public void LoadSamples()
        {
            Console.WriteLine("Code Samples:");
            
            this.samples = this.SampleReader.GetNames();

            for (int i = 0; i < samples.Count; i++)
            {
                Console.ForegroundColor = i % 2 == 0 ? ConsoleColor.Yellow : ConsoleColor.Green;
                Console.WriteLine( "{0}. {1}", i + 1, samples[i]);
            }

            Console.ResetColor();
            Console.WriteLine();

            AcceptingCommand();     //Simulate message loop
        }

        private void AcceptingCommand()
        {
            while (true)
            {
                Console.Write("Please enter action:");
                var cmd = Console.ReadLine().Trim().ToLower();
                if (String.IsNullOrEmpty(cmd)) break;

                switch (cmd)
                {
                    case "reload":
                    case "reset":
                        Console.Clear();
                        this.LoadSamples();
                        break;
                    case "clear":
                        Console.Clear(); break;
                    case "help":
                        break;
                    case "exit":
                        return;
                    default:
                        int index;
                        string sample = null;
                        if (int.TryParse(cmd, out index))
                        {
                            if (index <= this.samples.Count) sample = this.samples[index - 1];
                        }
                        else
                        {
                            sample = this.samples.FirstOrDefault(s => s.IndexOf(cmd, StringComparison.InvariantCultureIgnoreCase) >= 0);
                        }

                        if (String.IsNullOrEmpty(sample))
                        {
                            Console.ForegroundColor = ConsoleColor.Red;
                            Console.WriteLine("[{0}] can't be recognized.", cmd);
                        }
                        else
                        {                            
                            Console.WriteLine();
                            Console.ForegroundColor = ConsoleColor.Blue;
                            Console.WriteLine("Outputs:");
                            Console.ResetColor();

                            presenter.Run(sample);
                        }

                        Console.ResetColor();
                        break;
                }

            }
        }

        public void ShowCode(string sample)
        {
            throw new NotImplementedException();
        }

        public void Run(string source)
        {
        }

        public void ShowErrors(CompilerErrorCollection errorCollection)
        {
            if (errorCollection.Count < 1) return;
            Console.WriteLine("Error occurred:", ConsoleColor.Red);
            foreach (CompilerError error in errorCollection)
            {
                Console.WriteLine(error.ErrorText);
            }
            Console.WriteLine();
        }
        #endregion

        #region private

        void WriteLine(string value, ConsoleColor color)
        {
            Console.ForegroundColor = color;
            Console.WriteLine(value);
            Console.ResetColor();
        }


        [DllImport("kernel32")]
        static extern Boolean AllocConsole();
        [DllImport("kernel32")]
        static extern void FreeConsole();
        #endregion

    }
}
